#!/usr/bin/python3
# -*- coding:utf-8 -*-
# Create your views here.

from shutil import copyfile

import jsonpath

from django.http import JsonResponse
from django.http import HttpResponseRedirect
from django.shortcuts import render

from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET, require_POST

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

from djangoProject.settings import BASE_DIR

from job.src.function.basic_opration import *
from job.src.function.record_log import mylog
from markdown.models import MdFiles, MdSpace
from job.views import webPage
from markdown.src import __initData__
from markdown.src.luckysheet_update import readSheetData


class FileList(View):
    context = {}
    context.update(webPage)
    context['has_permission'] = True
    os.chdir(BASE_DIR)
    md_list = list(MdSpace.objects.filter(type='space').values())
    upload_option = jsonpath.jsonpath(md_list, '$..space')
    upload_path = jsonpath.jsonpath(md_list, '$..upload_dir')
    space_dic = dict(zip(upload_option, upload_path))

    @method_decorator(login_required)
    def get(self, request):
        space = request.GET.get('space', self.upload_option[0])
        filepath = request.GET.get('path', self.space_dic[space])
        mylog.info("space:" + space)
        mylog.info("filepath:" + filepath)
        self.get_data(space, filepath)
        return render(request, 'filelist.html', self.context)

    def post(self, request):
        space_key = request.POST.get('space')
        space_path = self.space_dic[space_key]
        res = MdFiles.objects.filter(doc_type='dir', space=space_key, upload_dir=space_path).exists()
        if not res:
            data = {'doc_type': 'dir', 'space': space_key, 'upload_dir': space_path, 'upload_name': space_key,
                    'cn_name': f'{space_key}的子目录'}
            MdFiles(**data).save()
            is_dir_exist(space_path)
        self.get_data(space_key, space_path)
        return render(request, 'filelist.html', self.context)

    def get_data(self, space, path):
        # 返回左侧的返回目录列表数据
        if space == "All":
            data_files = MdFiles.objects.values('space', 'upload_dir').distinct().order_by('upload_dir')
        else:
            data_files = MdFiles.objects.filter(space__startswith=space).values('space', 'upload_dir').distinct().order_by('upload_dir')
        data_files = list(data_files)
        mylog.info(data_files)
        self.context['dirList'] = self.subName(data_files)
        # 返回右侧的文件列表数据
        files = MdFiles.objects.filter(upload_dir=path).exclude(doc_type='dir').values('doc_type', 'upload_dir', 'upload_name', 'cn_name')
        # 增加如果是 .xlsx 类型用 edit_excel 编辑，否则用 edit_markdown 编辑器  2021-12-1
        self.context['filenames'] = [{'filepath': unit['upload_dir'] + unit['upload_name'], 'space': space, 'doc_type': unit['doc_type'],
            'filename': unit['upload_name'], 'description': unit['cn_name']} for unit in files]
        # 子目录重新排序
        self.upload_option.remove(space)
        self.upload_option.insert(0, space)
        self.context['upload_option'] = self.upload_option
        return self.context

    def subName(self, files: list) -> list:
        res_list = []
        for unit in files:
            dirname = unit['upload_dir'].split('static/')[1].replace('/', '.').rstrip('.')
            dirname = dirname.replace('markdown', '文档') if re.match(r'markdown', dirname) else dirname
            dirname = dirname.replace('uploadImage', '附件') if re.match(r'uploadImage', dirname) else dirname
            cur_dic = {'path': unit['upload_dir'], 'space': unit['space'], 'name': dirname}
            res_list.append(cur_dic)
        return res_list

@require_GET
def deleteFile(request):
    filepath = request.GET.get('filename')
    space = request.GET.get('space')
    fpath, fname = os.path.split(filepath)
    # 删除本地文件和数据库的文件路径存储信息
    delete_file(filepath)
    MdFiles.objects.filter(upload_name=fname).delete()
    return HttpResponseRedirect(f'/markdown/fileList/?path={fpath}/&space={space}')

@require_POST
@csrf_exempt
def deleteDir(request):
    context = {}
    link = request.POST.get('link')
    res = re.search(r'path=(.*).space=(.*)', link)
    if res:
        path, space = res[1], res[2]
        mylog.info(f'path: {path}')
    else:
        context['res'] = 'error! No path or space!'
        return JsonResponse(context)
    # 删除本地文件和数据库的文件路径存储信息
    files = os.listdir(path)
    if files:
        context['res'] = f'{path} 目录不为空，不能删除！'
        return JsonResponse(context)
    del_path = path.rstrip('/')
    delete_dir(del_path)
    fname = del_path.split('/')[-1]
    MdFiles.objects.filter(upload_name=fname).delete()
    context['res'] = f'{fname}目录已经删除！'
    return JsonResponse(context)

def getDirList(request):
    space = request.GET.get('space', 'common')
    mylog.info(f'space_key:{space}')
    # 返回左侧的返回目录列表数据
    if space == "All":
        data_files = MdFiles.objects.values('upload_dir').distinct()
    else:
        data_files = MdFiles.objects.filter(space__startswith=space).values('upload_dir').distinct()
    data_files = list(data_files)
    dirs_dict = [{'path': unit['upload_dir'], 'space': space,
                'name': unit['upload_dir'].split('static/')[1].replace('/', '.').rstrip('.')}
               for unit in data_files]
    return render(request, 'filelist_tableL.html', {"dirList": dirs_dict})



def getSpaceDirsList(request):
    space = request.GET.get('space')
    dirLst = MdFiles.objects.filter(space=space, upload_dir__contains='/markdown/').values("upload_dir").distinct()
    newlist = list()
    for unit in list(dirLst):
        unit['upload_dir'] = unit['upload_dir'].rstrip('/')
        mylog.info(f"unit: {unit}")
        newlist.append(unit)
    mylog.info(newlist)
    return JsonResponse({"spaceDirsList": newlist})

def moveFile(request):
    raw_file = request.POST.get('title')
    space = request.POST.get('space')
    upload_dir = request.POST.get('target_path')
    res = re.search(r'filename=(.*);space=(.*)', raw_file)
    if res:
        filename, raw_space = res[1], res[2]
        file = split_path(filename)
        new_file = upload_dir + '/' + file[1]
        copyfile(filename, new_file)
        MdFiles.objects.filter(upload_name=file[1]).update(upload_dir=upload_dir + '/', space=space)
        delete_file(filename)
    else:
        new_file = "源文件不存在，无法移动！"
    mylog.info(f"new_file: {new_file}")
    return JsonResponse({"res": new_file})

# --------------------------------upload.html-----------------------------------------
def handle_uploaded_file(f, save_name):
    with open(save_name, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

class UploadFile(View):
    context = {}
    md_list = list(MdSpace.objects.filter(type='space').values())
    upload_option = jsonpath.jsonpath(md_list, '$..space')
    upload_path = jsonpath.jsonpath(md_list, '$..upload_dir')
    context['upload_option'] = upload_option
    space_dic = dict(zip(upload_option, upload_path))
    create_dir(upload_path)
    def post(self, request):
        path_key = request.POST.get('op_type')
        upload_dir = request.POST.get('link')     # 上传时直接传递目录 20211126
        # upload_dir = self.space_dic[path_key]
        description = request.POST.get('description', None)
        f = request.FILES.get('file', None)
        if f:
            filename = f.name
            fn, ext = os.path.splitext(filename)
            save_name = upload_dir + filename
            # 上传文件保存到数据库
            data = {"doc_type": ext, "space": path_key, "upload_dir": upload_dir,
                    "upload_name": filename, "cn_name": description}
            exit_res = MdFiles.objects.filter(upload_name=filename).values().exists()
            if not exit_res:
                is_dir_exist(upload_dir)
                destination = open(save_name, 'wb+')
                for chunk in f.chunks():
                    destination.write(chunk)
                destination.close()
                MdFiles(**data).save()
                self.context['upload_path'] = save_name
            else:
                self.context['upload_path'] = f'{filename} 文件已存在，不允许文件名重复！'
            return render(request, 'upload.html', self.context)
        else:
            return render(request, 'upload.html', self.context)

    def get(self, request):
        param = request.GET.get('link', '')
        space = request.GET.get('space', '')
        res = re.search(r'path=(.*)', param)
        if res:
            self.context['link'] = res[1]
            self.context['upload_option'] = [space]
        mylog.info(self.context)
        return render(request, 'upload.html', self.context)

@require_POST
@csrf_exempt
def uploadFileDiv(request):
    context = {}
    link = request.POST.get('link')
    description = request.POST.get('description', '')
    mylog.info(f'link: {link}, description: {description}')
    f = request.FILES.get('file', None)
    mylog.info(f'files: {f}')
    res = re.search(r'path=(.*).space=(.*)', link)
    if res:
        upload_dir, space = res[1], res[2]
    else:
        context['upload_path'] = 'error! No path or space!'
        return JsonResponse(context)
    is_dir_exist(upload_dir)
    if f:
        filename = f.name
        fn, ext = os.path.splitext(filename)
        save_name = upload_dir + filename
        # 上传文件保存到数据库
        data = {"doc_type": ext, "space": space, "upload_dir": upload_dir,
                "upload_name": filename, "cn_name": description}
        exit_res = MdFiles.objects.filter(upload_name=filename).values().exists()
        if not exit_res:
            is_dir_exist(upload_dir)
            destination = open(save_name, 'wb+')
            for chunk in f.chunks():
                destination.write(chunk)
            destination.close()
            MdFiles(**data).save()
            context['upload_path'] = save_name
        else:
            context['upload_path'] = f'{filename} 文件已存在，不允许文件名重复！'
        return JsonResponse(context)
    else:
        context['upload_path'] = 'No file found!'
        return JsonResponse(context)

@require_POST
@csrf_exempt
def uploadExcel(request):
    context = {}
    link = request.POST.get('link')
    sheetdata = request.POST.get('sheetdata')
    desc = request.POST.get('description', '')
    # mylog.info(f"sheetdata: {sheetdata}")
    mylog.info(f'link: {link}, description: {desc}')
    res = re.search(r'path=(.*).space=(.*)', link)
    if res:
        upload_dir, space = res[1], res[2]
        is_dir_exist(upload_dir)
        sheetdata = json.loads(sheetdata)
        uploadfile = sheetdata['info']['name']
        file = split_path(uploadfile)
        if check_contain_chinese(file[2].encode('utf-8')):
            jname = "excel_" + get_curtime("%Y%m%d%H%M%S")
        else:
            jname = file[2]
        excelfile = jname + file[3]
        description = f"上传文件 {uploadfile} {desc}"
        filepath = upload_dir + excelfile
        sheets = readSheetData(sheetdata["sheets"])
        data = {"data": sheets}
        file_res = MdFiles.objects.filter(upload_name=excelfile).exists()
        if not file_res:
            write_json(filepath, data)
            datainfo = {"doc_type": '.xlsx', "space": space, "upload_dir": upload_dir,
                    "upload_name": excelfile, "cn_name": description}
            mylog.info(datainfo)
            MdFiles(**datainfo).save()
            context['upload_path'] = filepath
            return JsonResponse(context)
        else:
            context['upload_path'] = f'{excelfile} 已上传，不允许同名文件上传！'
            return JsonResponse(context)
    else:
        context['upload_path'] = 'error! No path or space!'
        return JsonResponse(context)


@require_POST
@csrf_exempt
def createFile(request):
    context = {}
    link = request.POST.get('link', '')
    name = request.POST.get('fileName')
    ext = request.POST.get('filetype')
    res = re.search(r'path=(.*).space=(.*)', link)
    if res:
        path, space = res[1], res[2]
    else:
        context['res'] = 'error! No path or space!'
        return JsonResponse(context)
    # 判断如果是文件，
    if ext == 'dir':
        filename = name
        upload_dir = path + name + '/'
        mylog.info(f'新增文件夹：{upload_dir}')
        is_dir_exist(upload_dir)
        desc = '这是一个目录'
    else:
        upload_dir = path
        fn = name.split('.')
        fname = fn[0] if len(fn) > 1 else name
        fn_ext = fn[1] if len(fn) > 1 else ext  # 给了后缀用真名
        if fn_ext == '.xlsx':
            if check_contain_chinese(fname.encode('utf-8')):
                jname = "excel_" + get_curtime("%Y%m%d%H%M%S")
            else:
                jname = fname
            filename = jname + fn_ext
            desc = f'新建文件 {fname}'
        elif fn_ext == '.md':
            filename = fname + fn_ext
            desc = f'新建文件 {filename}'
        else:
            filename = fname + fn_ext
            desc = f'新建文件 {filename}'
    # 数据库更新参数
    data = {"doc_type": ext, "space": space, "upload_dir": upload_dir,
            "upload_name": filename, "cn_name": desc}
    exit_res = MdFiles.objects.filter(upload_name=filename).values().exists()
    if not exit_res:
        filepath = path + filename
        if not os.path.exists(filepath) and ext != 'dir':
            if data['doc_type'] == '.xlsx':
                content = __initData__.sheetInitData
                sheet_json = {"data": content}
                # data.update({"text_content": json.dumps(sheet_json)})   // 文本保存到数据库取消
                write_json(filepath, sheet_json)
            else:
                with open(filepath, 'w', encoding='utf-8') as f:
                    f.write('')
                # data.update({"text_content": ""})
        MdFiles(**data).save()
        context['res'] = f"{filename}文件已新增成功"
    else:
        context['res'] = f"{filename}文件已存在"
    return JsonResponse(context)